package com.xtgg.sys;

import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.os.Vibrator;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.loopj.android.http.RequestParams;
import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.MemoryCacheAware;
import com.nostra13.universalimageloader.cache.memory.impl.LRULimitedMemoryCache;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.umeng.message.UmengRegistrar;
import com.xtgg.R;
import com.xtgg.main.MainPageActivity;
import com.xtgg.util.MgqDataHandler;
import com.xtgg.util.MgqRestClient;
import com.xtgg.util.PreferencesUtils;

public class DemoApp extends Application implements OnGetGeoCoderResultListener  {
	private static Context mContext;
	private List<Activity> activities = new ArrayList<Activity>();
	public List<String> mSafeArray = new ArrayList<String>();
	public List<BluetoothGatt> deviceInfo = new ArrayList<BluetoothGatt>();
	public String mCommid = "";
	public String mCommname = "";
	public String mCommtype = "";
	
	private LocationClient mLocationClient = null;
	GeoCoder mSearch = null;
	public double mLat = 0;
	public double mLng = 0;
	
	MediaPlayer player = null;
	
	public BluetoothAdapter mBluetoothAdapter;
	public GattCallback mGattCallback;
	
	BDLocationListener listener = new BDLocationListener() {
		@Override
		public void onReceiveLocation(BDLocation location) {
			if (location == null)
				return;
			
			mLat = location.getLatitude();
			mLng = location.getLongitude();
			
			sendHttpRequest();
			
			String userid = PreferencesUtils.getString(mContext, "userid");
			if(userid == null || userid.length() == 0) return;
			
			if(mSearch == null)
			{
				mSearch = GeoCoder.newInstance();
				mSearch.setOnGetGeoCodeResultListener(DemoApp.this);
			}
			
			LatLng ptCenter = new LatLng(mLat, mLng);
			mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(ptCenter));
		}

		public void onReceivePoi(BDLocation poiLocation) {
			
		}
	};
	
	private void sendHttpRequest() {
		MgqDataHandler loginHandler = new MgqDataHandler(this,
				false, false) {
			@Override
			public void onSuccess(String response) {
				
			}
		};
		

		RequestParams params = new RequestParams();
		params.put("act", "userlogin");
		params.put("mobile",PreferencesUtils.getString(this, "telephone"));
		params.put("password",PreferencesUtils.getString(this, "password"));
		params.put("device_token", UmengRegistrar.getRegistrationId(this));
		params.put("longitude", mLng);
		params.put("latitude", mLat);
		MgqRestClient.get(Constants.USERMGT, params, loginHandler);
	}
	
	public void startLocation()
	{
		mLocationClient = new LocationClient(this);
		mLocationClient.registerLocationListener(listener);
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType("bd09ll"); // 设置坐标类型
		option.setScanSpan(1800000);
		mLocationClient.setLocOption(option);
		mLocationClient.start();
	}
	
	public String mAddress = "";
	@SuppressWarnings("deprecation")
	@Override
	public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
		if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
			return;
		}

//		mLocationClient.stop();
		MgqDataHandler loginHandler = new MgqDataHandler(this, false, false) {
			@Override
			public void onSuccess(String response) {
				
			}
		};
		
		Date date = new Date(System.currentTimeMillis());
		mAddress = result.getAddress();
		
		RequestParams params = new RequestParams();
		params.put("act", "addFootMark");
		params.put("userid", PreferencesUtils.getString(this, "userid"));
		params.put("province",result.getAddressDetail().province);
		params.put("city",result.getAddressDetail().city);
		params.put("place",result.getAddress());
		params.put("year",String.valueOf(1900 + date.getYear()));
		params.put("month",String.valueOf(date.getMonth() + 1));
		params.put("latitude",mLat);
		params.put("longitude",mLng);
		MgqRestClient.get(Constants.INFOMGT, params, loginHandler);
	}
	
	@Override
	public void onGetGeoCodeResult(GeoCodeResult result) {}
	
	public static Context getContext() {
		return mContext;
	}

	@SuppressLint("NewApi")
	@Override
	public void onCreate() {
		super.onCreate();

		mContext = getApplicationContext();

		mCommid = PreferencesUtils.getString(this, "commid", "");
		mCommname = PreferencesUtils.getString(this, "commname", "");
		mCommtype = PreferencesUtils.getString(this, "commtype", "");

		if (Constants.DEBUG_MODE
				&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
			StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
					.detectDiskReads().detectDiskWrites().detectNetwork() // or
																			// .detectAll()
																			// for
																			// all
																			// detectable
																			// problems
					.penaltyLog().build());
			StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
					.detectLeakedSqlLiteObjects().penaltyLog().build());
		}

		if (!Constants.DEBUG_MODE) {
			MyUncaughtExceptionHandler exceptionHandler = MyUncaughtExceptionHandler
					.getExceptionHandler(getApplicationContext());
			Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
		}

		initImageLoader(getApplicationContext());
		SDKInitializer.initialize(getApplicationContext());

		startLocation();

		mBluetoothAdapter = ((BluetoothManager)getSystemService("bluetooth")).getAdapter();
		mGattCallback = new GattCallback();
		
//		AutoScan();
	}

	public void addActivity(Activity activity) {

		activities.add(activity);
	}

	public void removeActivity(Activity activity) {
		activities.remove(activity);
	}

	public List<Activity> getActivityList() {
		return activities;
	}

	@Override
	public void onTerminate() {

		super.onTerminate();

		mLocationClient.unRegisterLocationListener(listener);
		mLocationClient.stop();
		
		exit();
	}

	public void exit() {
		for (Activity activity : activities) {
			activity.finish();
		}
		System.exit(0);
	}

	public int getActivitySize() {
		return activities.size();
	}

	public static boolean isIntentAvailable(Context context, Intent intent) {
		final PackageManager packageManager = context.getPackageManager();
		List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
				PackageManager.GET_ACTIVITIES);
		return list.size() > 0;
	}

	public static void initImageLoader(Context context) {
		int memoryCacheSize = (int) (Runtime.getRuntime().maxMemory() / 3);

		MemoryCacheAware<String, Bitmap> memoryCache;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
			memoryCache = new LruMemoryCache(memoryCacheSize);
		} else {
			memoryCache = new LRULimitedMemoryCache(memoryCacheSize);
		}

		// This configuration tuning is custom. You can tune every option, you
		// may tune some of them,
		// or you can create default configuration by
		// ImageLoaderConfiguration.createDefault(this);
		// method.
		ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
				context).threadPriority(Thread.NORM_PRIORITY - 2)
				.memoryCache(memoryCache).denyCacheImageMultipleSizesInMemory()
				.discCacheFileNameGenerator(new Md5FileNameGenerator())
				.tasksProcessingOrder(QueueProcessingType.FIFO).build();
		// .tasksProcessingOrder(QueueProcessingType.LIFO).build();

		// Initialize ImageLoader with configuration.
		ImageLoader.getInstance().init(config);
		// com.nostra13.universalimageloader.utils.L.setLogEnable(false);
	}
	
	@SuppressLint("NewApi")
	private class GattCallback extends BluetoothGattCallback
	{
		private GattCallback()
		{
	    }
		
		public void onCharacteristicChanged(final BluetoothGatt paramBluetoothGatt, BluetoothGattCharacteristic paramBluetoothGattCharacteristic)
	    {
			
/*	      if (paramBluetoothGattCharacteristic.getValue()[0] == 1)
	      {
	        if (!isPreviousCommandHandling)
	          break label87;
	        Log.i("CALM", "ACTION_DEV_DOUBLE_CLICK---------");
	        BleService.this.mCommandHanler.removeCallbacksAndMessages(null);
	        BleService.this.isPreviousCommandHandling = false;
	        if (SettingSp.getInstance(BleService.this).getDoubleClick() == 0)
	          BleService.this.broadcastUpdate("com.fb.ble.action.find_waring", paramBluetoothGatt.getDevice().getAddress());
	      }
	      else
	      {
	        return;
	      }
	      BleService.this.broadcastUpdate("com.fb.ble.action.audio_record");
	      return;
	      label87: BleService.this.isPreviousCommandHandling = true;
	      BleService.this.mCommandHanler.postDelayed(new Runnable()
	      {
	        public void run()
	        {
	          BleService.this.isPreviousCommandHandling = false;
	          BleService.this.broadcastUpdate("com.fb.ble.action.device_single_click", paramBluetoothGatt.getDevice().getAddress(), paramBluetoothGatt.getDevice().getName());
	          Log.i("CALM", "ACTION_DEV_SINGLE_CLICK-------------------");
	        }
	      }
	      , 500L);*/
	    }

	    public void onCharacteristicRead(BluetoothGatt paramBluetoothGatt, BluetoothGattCharacteristic paramBluetoothGattCharacteristic, int paramInt)
	    {
	    	
	    }

		public void onConnectionStateChange(BluetoothGatt paramBluetoothGatt, int paramInt1, int paramInt2)
	    {
	    	Intent intent = null;
	    	
	    	if(paramInt2 == BluetoothProfile.STATE_CONNECTED)
	    	{
	    		if(!deviceInfo.contains(paramBluetoothGatt))
	    		{
	    			intent = new Intent("com.fb.ble.action.device_connect");
	    			deviceInfo.add(paramBluetoothGatt);
	    			intent.putExtra("connect", "1");
	    		}
	    	}
	    	else if(paramInt2 == BluetoothProfile.STATE_DISCONNECTED)
	    	{
	    		if(deviceInfo.contains(paramBluetoothGatt))
	    		{
	    			intent = new Intent("com.fb.ble.action.device_connect");
	    			
	    			List<BluetoothGatt> list = ((DemoApp)getApplicationContext()).deviceInfo;
	    			int size = list.size();
	    			for(int j = size - 1; j >= 0; j--)
	    			{
	    				if(paramBluetoothGatt.getDevice().getAddress().contains(list.get(j).getDevice().getAddress()))
	    				{
	    					list.get(j).disconnect();
	    					deviceInfo.remove(j);
	    				}
	    			}
	    			intent.putExtra("connect", "0");
	    			
	    			if(!MainPageActivity.mManulDisconnect)
					{
						try {
					    	int mRing = PreferencesUtils.getInt(mContext, "ring_type");
							if(mRing < 0) mRing = 0;
					    	
							if(mRing == 0 || mRing == 2)
							{
								if(player != null)
								{
									if(player.isPlaying()) player.stop();
									player = null;
								}
								
								player = MediaPlayer.create(mContext, R.raw.warn0 + mRing);//.setDataSource("http://data.huiyi8.com/2014/lxy/05/15/2.mp3");
								if(player != null)
								{
									player.stop();
								}
								
								player.prepareAsync();
							    player.setOnPreparedListener(new OnPreparedListener()
							    {
									@Override
									public void onPrepared(MediaPlayer arg0) {
										player.start();
									}
							    });
							}
							
							if(mRing == 1 || mRing == 2)
							{
								Vibrator mVibrator01 = ( Vibrator ) getSystemService(Service.VIBRATOR_SERVICE);  
				                mVibrator01.vibrate( new long[]{100,10,100,5000},-1);  
							}
						} catch (Exception e) {
							e.printStackTrace();
						} 
					}
	    		}
	    	}
	    	
	    	if(intent != null)
	    	{
    			intent.putExtra("address", paramBluetoothGatt.getDevice().getAddress());
	    		sendBroadcast(intent);
	    	}
	    }

	    public void onReadRemoteRssi(BluetoothGatt paramBluetoothGatt, int paramInt1, int paramInt2)
	    {
	    }

	    public void onServicesDiscovered(BluetoothGatt paramBluetoothGatt, int paramInt)
	    {
	      if (paramInt == 0)
	      {
	    	  
	 /*       BleService.this.broadcastUpdate("com.fb.ble.action.device_gatt_services_discovered", paramBluetoothGatt.getDevice().getAddress());
	        BleService.this.enablePeerDeviceNotifyMe(paramBluetoothGatt, true);
	        UUID localUUID1 = BleGattAttributes.UUID_IMMIDIATE_ALERT_SERVICEL;
	        UUID localUUID2 = BleGattAttributes.UUID_ALERT_LEVEL_CHARACTERISTIC;
	        paramBluetoothGatt.readCharacteristic(BleService.this.getCharacteristic(paramBluetoothGatt.getDevice().getAddress(), localUUID1, localUUID2));*/
	      }
	    }
	}
	
	GattCallbackAuto mAutoGattCallback = null;
	@SuppressLint("NewApi")
	private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback()
	{
		private void mLeScan(String paramAnonymousString1, String paramAnonymousString2)
	    {
			if(mAutoGattCallback == null) mAutoGattCallback = new GattCallbackAuto();
			if (paramAnonymousString2 != null && paramAnonymousString2.contains("SE100"))
			{
				BluetoothDevice localBluetoothDevice = mBluetoothAdapter.getRemoteDevice(paramAnonymousString1);
				localBluetoothDevice.connectGatt(mContext,false,mAutoGattCallback);
			}
	    }

	    public void onLeScan(BluetoothDevice paramAnonymousBluetoothDevice, int paramAnonymousInt, byte[] paramAnonymousArrayOfByte)
	    {
	    	mLeScan(paramAnonymousBluetoothDevice.getAddress(), paramAnonymousBluetoothDevice.getName());
	    }
	};
	
	@SuppressLint("NewApi")
	void AutoScan()
	{
		final Handler handle = new Handler()
		{
			public void handleMessage(Message msg)
			{
				String userid = PreferencesUtils.getString(mContext, "userid");
				if(userid == null || userid.length() == 0) return;
				
				if(!BluetoothAdapter.getDefaultAdapter().isEnabled())
				{
					BluetoothAdapter.getDefaultAdapter().enable();
				}
				((DemoApp)getApplicationContext()).mBluetoothAdapter.startLeScan(mLeScanCallback);
			}
		};
		
		new Timer().schedule(new TimerTask()
		{
			@Override
			public void run() {
				handle.sendEmptyMessage(1);
			}
		}, 10000,300000);
	}
	
	@SuppressLint("NewApi")
	private class GattCallbackAuto extends BluetoothGattCallback
	{
		private GattCallbackAuto()
		{
	    }
		
		public void onCharacteristicChanged(final BluetoothGatt paramBluetoothGatt, BluetoothGattCharacteristic paramBluetoothGattCharacteristic)
	    {}

		@SuppressWarnings("deprecation")
	    public void onCharacteristicRead(BluetoothGatt paramBluetoothGatt, BluetoothGattCharacteristic paramBluetoothGattCharacteristic, int paramInt)
	    {
			String mSerial = new String(paramBluetoothGattCharacteristic.getValue());
			paramBluetoothGatt.close();
			
			MgqDataHandler loginHandler = new MgqDataHandler(mContext, false, false) {
				@Override
				public void onSuccess(String response) {
					JSONObject ruser = JSON.parseObject(response);

					if (ruser.getString("state").equals("1")) {
					} 
				}
			};

			RequestParams params = new RequestParams();
			params.put("act", "atuoScanDevice");
			params.put("devicenumber", mSerial);
			params.put("place", mAddress);
			params.put("userid", PreferencesUtils.getString(mContext, "userid"));
			MgqRestClient.post(Constants.DEVICEMGT, params, loginHandler);
	    }

		public void onConnectionStateChange(BluetoothGatt paramBluetoothGatt, int paramInt1, int paramInt2)
	    {
	    	Intent intent = null;
	    	
	    	if(paramInt2 == BluetoothProfile.STATE_CONNECTED)
	    	{
	    		final BluetoothGatt mConnect = paramBluetoothGatt;
	    		mConnect.connect();
				mConnect.discoverServices();
				
				try{
					final Handler handle = new Handler()
					{
						public void handleMessage(Message msg)
						{
							BluetoothGattService localBluetoothGattService = mConnect.getService(UUID.fromString("0000180A-0000-1000-8000-00805f9b34fb"));
							if(localBluetoothGattService != null)
							{
								BluetoothGattCharacteristic localBluetoothGattCharacteristic = localBluetoothGattService.getCharacteristic(UUID.fromString("00002a25-0000-1000-8000-00805f9b34fb"));
						        mConnect.readCharacteristic(localBluetoothGattCharacteristic);
							}
						}
					};
					
					new Timer().schedule(new TimerTask()
					{
						@Override
						public void run() {
							handle.sendEmptyMessage(1);
						}
					}, 2000);
				}catch(Exception e){}
	    	}
	    }

	    public void onReadRemoteRssi(BluetoothGatt paramBluetoothGatt, int paramInt1, int paramInt2)
	    {
	    }

	    public void onServicesDiscovered(BluetoothGatt paramBluetoothGatt, int paramInt)
	    {
	    }
	}
}
